import { rootValue } from '@/utils/pxtorem'
import proj4 from 'proj4'

import pinyin from 'pinyin'
import * as XLSX from 'xlsx'
/**
 * 文字转拼音
 * @param text 文字
 * @returns
 */
export function convertToPinyin(text: string) {
	const pinyinResult = pinyin(text, {
		style: pinyin.STYLE_NORMAL,
		heteronym: false,
	})
	return pinyinResult.map((item: any) => item[0]).join(' ')
}
/**
 * <p> 获取加载图片地址 </p>
 * examples: bg/bg.png
 * @param imgPath: string
 */
export const requireImg = (imgPath: string) => {
	return new URL(`../assets/images/${imgPath}`, import.meta.url).href
}

/**
 * px转换rem
 */
export function pxToRem(px: number | string) {
	if (px == '100%') {
		return px
	} else {
		return `${(px as number) / rootValue}rem`
	}
}

/**
 * 格式化树状结构
 * @param beforeInfotreeData 原始数据数组
 * @returns 格式化后的树状结构
 */
export const formatTree = (beforeInfotreeData: any[]) => {
	const map: { [index: number]: any } = {}
	const val: any[] = []

	beforeInfotreeData.forEach((item) => {
		map[item.index] = item
		if (item.parentIndex !== 0) {
			if (!map[item.parentIndex].children) {
				map[item.parentIndex].children = []
			}
			map[item.parentIndex].children.push(item)
		} else {
			val.push(item)
		}
	})

	return val
}
/**
 * 两个点计算出矩形
 * @param point1 number[]
 * @param point2 number[]
 * @param height number[]
 * @returns
 */
export const calculateRectangleCoordinates = (point1: number[], point2: number[], height: number) => {
	let x1 = point1[0]
	let y1 = point1[1]
	let x2 = point2[0]
	let y2 = point2[1]

	let slope = (y2 - y1) / (x2 - x1)
	let angle = Math.atan(slope)

	let dx = height * Math.sin(angle)
	let dy = height * Math.cos(angle)

	let topLeft = [x1 - dx, y1 + dy]
	let topRight = [x2 - dx, y2 + dy]
	let bottomLeft = [x1 + dx, y1 - dy]
	let bottomRight = [x2 + dx, y2 - dy]

	return [topLeft, topRight, bottomRight, bottomLeft]
}
/**
 * EPSG4547 坐标系转  WGS84 坐标系
 * @param lngLat 二维或者三维经纬度坐标数组
 * @param height 高度
 * @returns 经纬度坐标数组
 */
export function EPSG4547_To_EPSG4326(xy: number[] | number[][]) {
	proj4.defs('EPSG:4326', '+proj=longlat +datum=WGS84 +no_defs')
	proj4.defs('EPSG:4547', '+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs')
	if (!xy.length) return []

	const coodi = Array.isArray(xy[0]) ? xy : [xy]

	return coodi.map((item: any) => {
		return proj4('EPSG:4547', 'EPSG:4326', [item[0], item[1]])
	})
}
/**
 *延时器
 */
export const delay = (delay: number) => {
	return new Promise((resolve) => {
		setTimeout(() => {
			resolve(true)
		}, delay)
	})
}
/**
 * WGS84 坐标系转 EPSG4547 坐标系
 * @param lngLat 二维或者三维经纬度坐标数组
 * @param height 高度
 * @returns 经纬度坐标数组
 */
export function EPSG4326_To_EPSG4547(lngLat: number[] | number[][], height = 0) {
	proj4.defs('EPSG:4326', '+proj=longlat +datum=WGS84 +no_defs')
	proj4.defs('EPSG:4547', '+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs')
	if (!lngLat.length) return []

	const coodi = Array.isArray(lngLat[0]) ? lngLat : [lngLat]

	return coodi.map((item: any) => {
		const xyz = proj4('EPSG:4326', 'EPSG:4547', [item[0], item[1]])
		xyz.push(height)
		return xyz
	})
}

/**
 * 将 WKT (Well-Known Text，一种表示空间几何对象的文本格式) 转换为坐标数组。
 * @param wkt WKT字符串，例如 "POINT(116 40)" 或 "LINESTRING(116 40, 117 41)"。
 * @returns {Array<Array<number>>} 转换后的坐标数组，每个坐标为一个包含 x 和 y 的数组。
 */
export function wktTo4547Coodinate(wkt: string, height: number = 0) {
	// 函数内部定义一个空数组用于存储转换后的坐标
	const coordinates = []

	// 通过正则表达式匹配 WKT 数据中的坐标部分
	const regex = /[+-]?\d+\.\d+\s[+-]?\d+\.\d+/g
	let match
	while ((match = regex.exec(wkt)) !== null) {
		// 对于每个匹配到的坐标字符串，使用空格分割并转换为数字，然后存入数组
		const coords = match[0].split(' ').map(parseFloat)
		coordinates.push(coords)
	}

	return EPSG4326_To_EPSG4547(coordinates, height)
}
/**
 * 将坐标数组转换为 WKT (Well-Known Text) 格式。
 * @param coordinates 坐标数组，每个坐标为一个包含 x 和 y 的数组。
 * @param geometryType 几何类型，例如 "POINT"、"LINESTRING" 或 "POLYGON"。
 * @returns {string} 转换后的 WKT 字符串。
 */
export function coordinatesToWKT(coordinates: number[][], geometryType = 'POLYGON') {
	let wkt = ''
	coordinates = coordinates.map((coord: number[]) => coord.slice(0, -1))
	coordinates = EPSG4547_To_EPSG4326(coordinates)

	// 根据几何类型添加对应的 WKT 标识
	switch (geometryType.toUpperCase()) {
		case 'POINT':
			wkt += 'POINT '
			break
		case 'LINESTRING':
			wkt += 'LINESTRING '
			break
		case 'POLYGON':
			wkt += 'POLYGON (('
			break
		default:
			throw new Error('Unsupported geometry type.')
	}

	// 添加坐标数据
	coordinates.forEach((point: any, index) => {
		if (index > 0) {
			wkt += ', '
		}
		wkt += point.join(' ')
	})

	// 对于多边形，添加结束标识
	if (geometryType.toUpperCase() === 'POLYGON') {
		wkt += '))'
	}

	return wkt
}

export const copyText = (el: HTMLElement) => {
	const text = el.innerText
	let clipboard = navigator.clipboard || {
		writeText: (text) => {
			let copyInput = document.createElement('textarea')
			copyInput.value = text
			document.body.appendChild(copyInput)
			copyInput.select()
			document.execCommand('copy')
			document.body.removeChild(copyInput)
		},
	}

	clipboard.writeText(text)
}

// export function interpolateCurve(points: number[][], numPoints: number) {
// 	const interpolatedPoints = []

// 	// 计算段数
// 	const totalSegments = points.length - 1

// 	// // 将第一个点添加到插值点数组中
// 	// if (numPoints > 0) {
// 	// 	interpolatedPoints.push(points[0])
// 	// }

// 	// 如果需要生成 numPoints 个点，分配到每个段
// 	const pointsPerSegment = Math.floor((numPoints - 1) / totalSegments)
// 	const remainingPoints = (numPoints - 1) % totalSegments

// 	for (let i = 0; i < totalSegments; i++) {
// 		const p0 = points[Math.max(0, i - 1)]
// 		const p1 = points[i]
// 		const p2 = points[i + 1]
// 		const p3 = Math.min(i + 2, points.length - 1) === points.length - 1 ? p2 : points[i + 2]

// 		// 计算在每个段的点数，包括当前段的点
// 		const segmentNumPoints = pointsPerSegment + (i < remainingPoints ? 1 : 0)

// 		for (let j = 0; j < segmentNumPoints; j++) {
// 			const t = j / segmentNumPoints

// 			// 使用 Catmull-Rom 样条插值
// 			const x =
// 				0.5 *
// 				(2 * p1[0] +
// 					(-p0[0] + p2[0]) * t +
// 					(2 * p0[0] - 5 * p1[0] + 4 * p2[0] - p3[0]) * t * t +
// 					(-p0[0] + 3 * p1[0] - 3 * p2[0] + p3[0]) * t * t * t)

// 			const y =
// 				0.5 *
// 				(2 * p1[1] +
// 					(-p0[1] + p2[1]) * t +
// 					(2 * p0[1] - 5 * p1[1] + 4 * p2[1] - p3[1]) * t * t +
// 					(-p0[1] + 3 * p1[1] - 3 * p2[1] + p3[1]) * t * t * t)

// 			const z =
// 				0.5 *
// 				(2 * p1[2] +
// 					(-p0[2] + p2[2]) * t +
// 					(2 * p0[2] - 5 * p1[2] + 4 * p2[2] - p3[2]) * t * t +
// 					(-p0[2] + 3 * p1[2] - 3 * p2[2] + p3[2]) * t * t * t)

// 			interpolatedPoints.push([x, y, z])
// 		}
// 	}

// 	// 添加最后一个点，确保最后一个点是输入曲线的最后一个点
// 	if (numPoints > 1) {
// 		interpolatedPoints.push(points[points.length - 1])
// 	}

// 	// 确保总点数为 numPoints
// 	if (interpolatedPoints.length > numPoints) {
// 		return interpolatedPoints.slice(0, numPoints + 1)
// 	}

// 	return interpolatedPoints
// }

export function interpolateCurve(points: any, numPoints: any) {
	const interpolatedPoints = []

	// 计算段数
	const totalSegments = points.length - 1

	// 添加起始点
	if (numPoints > 0) {
		interpolatedPoints.push(points[0])
	}

	// 计算总插值点数
	const totalPoints = numPoints - 1 // 除去第一个点
	const segmentsPerPoint = totalPoints / totalSegments

	for (let i = 0; i < totalSegments; i++) {
		const p0 = points[i]
		const p1 = points[i + 1]

		for (let j = 0; j < segmentsPerPoint; j++) {
			const t = j / segmentsPerPoint
			const x = (1 - t) * p0[0] + t * p1[0]
			const y = (1 - t) * p0[1] + t * p1[1]
			const z = (1 - t) * p0[2] + t * p1[2]

			interpolatedPoints.push([x, y, z])
		}
	}

	// 添加最后一个点，确保最后一个点是输入曲线的最后一个点
	if (numPoints > 1) {
		interpolatedPoints.push(points[points.length - 1])
	}

	return interpolatedPoints
}

/**
 * 计算多边形中心点
 * @param vertices
 * @returns
 */
export function calculateCentroid3D(vertices: any) {
	if (vertices.length === 0) {
		throw new Error('顶点数组不能为空')
	}

	let xSum = 0
	let ySum = 0
	let zSum = 0

	for (const vertex of vertices) {
		xSum += vertex[0] // 假设 vertex 是 [x, y, z] 格式的数组
		ySum += vertex[1]
		zSum += vertex[2]
	}

	const centroid = [xSum / vertices.length, ySum / vertices.length, zSum / vertices.length]
	return centroid
}

/**
 * [0,100]的进度数与时间之间的转换 '12:00'  30
 */
export const convertToTime = {
	numTotime: (param: number) => {
		const totalMinutes = Math.round((param / 100) * (24 * 60 - 6 * 60) + 6 * 60)
		const hours = Math.floor(totalMinutes / 60)
		const minutes = totalMinutes % 60
		return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`
	},
	timeTonum: (param: string) => {
		const [hours, minutes] = param.split(':').map(Number)
		// 将小时和分钟转换为总分钟数
		const totalMinutes = hours * 60 + minutes

		// 定义总时间范围（从6:00到24:00）
		const totalTimeRange = (24 - 6) * 60

		// 计算百分比
		const percentage = ((totalMinutes - 6 * 60) / totalTimeRange) * 100

		// 返回百分比，确保在0到100之间
		return Math.max(0, Math.min(100, percentage))
	},
}

export const personsSetting = {
	//控制人流速度
	setSpeed: (speed: number) => {
		fdapi.misc.callBPFunction({
			objectName: 'BP_control_000_2',
			functionName: 'control_speed000',
			parameters: [
				{
					paramType: BPFuncParamType.Float,
					paramValue: speed * 20 < 50 ? 50 : speed * 20, //取值50-450
				},
			],
		})
		fdapi.misc.callBPFunction({
			objectName: 'BP_control11_5',
			functionName: 'control_speed',
			parameters: [
				{
					paramType: BPFuncParamType.Float,
					paramValue: speed * 20 < 50 ? 50 : speed * 20, //取值50-450
				},
			],
		})
	},

	setTotal: (total: number) => {
		//控制人员数量
		fdapi.misc.callBPFunction({
			objectName: 'BP_control_000_2',
			functionName: 'control_people000',
			parameters: [
				{
					paramType: BPFuncParamType.Float,
					paramValue: total, //取值几百吧
				},
			],
		})
		fdapi.misc.callBPFunction({
			objectName: 'BP_control11_5',
			functionName: 'control_people',
			parameters: [
				{
					paramType: BPFuncParamType.Float,
					paramValue: total, //取值几百吧
				},
			],
		})
	},
	getLine: async () => {
		//获取路线的坐标点
		return new Promise(async (resolve) => {
			const data = await fdapi.misc.callBPFunction({
				objectName: 'yeyazhijia_control_2',
				functionName: 'get_position', //路线坐标名称+对应点坐标，会打印出来
			})
			resolve(data)
		})
	},
}

/**
 * 导入excel表格转换成json数据
 * @param file 文件对象
 * @returns
 */

export function convertExcelToJson(file: any) {
	return new Promise((resolve, reject) => {
		const reader = new FileReader()

		reader.onload = (e: any) => {
			const data = new Uint8Array(e.target.result)
			const workbook = XLSX.read(data, { type: 'array' })
			const jsonSheet = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]])

			// 假设将 JSON 数据处理成适合 el-table 的格式
			const formattedData = jsonSheet.map((item: any) => {
				return {
					// 假设 Excel 每列名为 '列1', '列2', '列3' 可以按需修改
					trainNum: item['__EMPTY'],
					type: item['__EMPTY_1'],
					startStation: item['__EMPTY_2'],
					endStation: item['__EMPTY_3'],
					arrivalTime: item['__EMPTY_4'],
					departureTime: item['__EMPTY_5'],
					parkingTime: item['__EMPTY_6'],
					actualArrivalTime: item['__EMPTY_7'],
					actualDrivingTime: item['__EMPTY_8'],
					actualParkingTime: item['__EMPTY_9'],
					ticketGate: item['__EMPTY_10'],
					channel: item['__EMPTY_11'],
					marshalling: item['__EMPTY_12'],
					Model: item['__EMPTY_13'],
					takeResponsibility: item['__EMPTY_14'],
					peopleBoarding: item['__EMPTY_15'],
					peopleGetting: item['__EMPTY_16'],
					transfersNum: item['__EMPTY_17'],
					BeijingNum: item['__EMPTY_18'],
					shanghaiNum: item['__EMPTY_19'],
				}
			})
			resolve(formattedData)
		}

		reader.onerror = (error) => {
			reject(error)
		}

		reader.readAsArrayBuffer(file)
	})
}

//使用方法

// const fileInput = document.getElementById('file-input');
// fileInput.addEventListener('change', (event) => {
//     const file = event.target.files[0];
//     convertExcelToJson(file).then((jsonString) => {
//         console.log(jsonString);
//         // 此处可以将 jsonString 赋值给 el-table 的 data
//     }).catch((error) => {
//         console.error('Error reading file:', error);
//     });
// });
